﻿using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq.Expressions;

namespace Faml.Frontend
{
    public class FamlExpressionExtension
    {
        private int hash = 0;

        public int Hash
        {
            get { return hash; }
            set { hash = value; }
        }

        private int height = 1;

        public int Height
        {
            get { return height; }
            internal set
            {
                height = value;
            }
        }

        private bool nonBreakable = false;

        /// <summary>
        /// True means that children of this expression should not be extracted.
        /// </summary>
        public bool NonBreakable
        {
            get { return nonBreakable; }
            set { nonBreakable = value; }
        }

        /// <summary>
        /// Gets the value indicating that this FamlExpression doesn't depend on any parameter.
        /// </summary>
        public bool IsIndependent
        {
            get { return parameters.Count == 0; }
        }

        private List<FamlLambdaParameter> parameters = new List<FamlLambdaParameter>();

        public ReadOnlyCollection<FamlLambdaParameter> DependsOnParameters
        {
            get { return parameters.AsReadOnly(); }
        }

        public void AddIfNotExist(ReadOnlyCollection<FamlLambdaParameter> np)
        {
            foreach (FamlLambdaParameter p in np)
            {
                int i = parameters.BinarySearch(p, ParameterComparer.Comparer);
                if (i < 0)
                    parameters.Insert(~i, p);
            }
        }

        public void AddIfNotExist(FamlLambdaParameter p)
        {
            int i = parameters.BinarySearch(p, ParameterComparer.Comparer);
            if (i < 0)
                parameters.Insert(~i, p);
        }

        private class ParameterComparer : IComparer<FamlLambdaParameter>
        {
            public readonly static ParameterComparer Comparer = new ParameterComparer();

            #region IComparer<FamlLambdaParameter> Members

            public int Compare(FamlLambdaParameter x, FamlLambdaParameter y)
            {
                return (x == y) ? 0 : 1;//string.Compare(x.Name, y.Name);
            }

            #endregion
        }
    }
}
